package basic

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"math"
	"os"
	"strings"
)

// 逐行读取文本文件
func readTextFileByLine(file string) {
	fil, err := os.Open(file)

	if err != nil {
		log.Fatalf("无法打开文件: %v", err)
	}

	// 关闭文件io
	defer fil.Close()

	scanner := bufio.NewScanner(fil)
	for scanner.Scan() {
		fmt.Println(scanner.Text())
	}

	if err := scanner.Err(); err != nil {
		log.Fatalf("读取文件时出错: %v", err)
	}
}

// 拆分后逐行获取文本文件内容
func splitTextFile(file string) {
	fin, err := os.Open(file)

	if err != nil {
		log.Fatal(err)
	}

	defer fin.Close()

	const count = 4.0

	info, err := fin.Stat()
	if err != nil {
		log.Fatalf("无法获取文件信息: %v", err)
	}

	size := info.Size()                          // 获取文件大小
	seg := int(math.Ceil(float64(size) / count)) // 文件分割为指定段，计算每段的大小
	fmt.Printf("文件总大小为: %d\n每段大小为: %d\n", size, seg)

	for {
		buffer := make([]byte, seg)
		n, err := fin.Read(buffer)
		if err != nil {
			if err != io.EOF {
				log.Fatalf("读取文件时出错: %v", err)
			} else {
				if n > 0 {
					fmt.Print(string(buffer[:n]))
				}
				break
			}
		} else {
			fmt.Print(string(buffer[:n]))
		}
	}
}

func splitBinaryFile(file string) {
	baseName := file
	suffix := ""

	pos := strings.LastIndex(file, ".")

	if pos >= 0 {
		baseName = file[:pos]
		suffix = file[pos:]
	}

	fil, err := os.Open(file)
	if err != nil {
		log.Fatalf("无法打开文件: %v", err)
	}

	defer fil.Close()

	const count = 4

	// 获取文件基础信息
	info, err := fil.Stat()

	if err != nil {
		log.Fatalf("无法获取文件信息: %v", err)
	}

	fileSize := info.Size()
	segmentSize := (fileSize + count - 1) / count // 计算每个分段的大小

	// 将文件拆分成指定数量的部分
	for i := 0; i < count; i++ {
		outFile := fmt.Sprintf("%s_part_%d%s", baseName, i+1, suffix)

		fout, err := os.Create(outFile)
		// fout, err := os.OpenFile(outFile, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, os.ModePerm)
		if err != nil {
			log.Fatalf("文件写入失败: %v", err)
		}

		buffer := make([]byte, segmentSize)
		n, err := fil.Read(buffer)
		if err != nil && err != io.EOF {
			fout.Close()
			log.Fatalf("文件读取失败: %v", err)
		}

		// 将读取到的字节写入输出文件
		if _, err := fout.Write(buffer[:n]); err != nil {
			fout.Close()
			log.Fatalf("文件写入失败: %v", err)
		}

		// 关闭输出文件
		if err := fout.Close(); err != nil {
			log.Fatalf("无法关闭文件: %v", err)
		}

		// 如果已到文件末尾，退出循环
		if err == io.EOF {
			break
		}
	}
}
